
#include "nxdat.mini.api.h"
#include <string>
#include <vector>
#include <Windows.h>
using namespace std;

namespace dx{

	inline static char* dx_type_to_string(e_dx_type_t ty)
	{
	   static char* type_map[] ={
		"null",
		"int",
		"real",
		"vector2",
		"vector3",
		"vector4",
		"string",
		"wstring",
		"node",
		"list",
		"map",
		"table"
	   };
	   return type_map[ty];
	};

	inline e_dx_type_t parse_dx_type(const char* ty)
	{
		if (strcmp(ty, "int") == 0)return dxint;
		if (strcmp(ty, "real") == 0)return dxreal;
		if (strcmp(ty, "vector2") == 0)return dxvector2;
		if (strcmp(ty, "vector3") == 0)return dxvector3;
		if (strcmp(ty, "vector4") == 0)return dxvector4;
		if (strcmp(ty, "string") == 0)return dxstring;
		if (strcmp(ty, "wstring") == 0)return dxwstring;
		if (strcmp(ty, "node") == 0)return dxnode;
		if (strcmp(ty, "list") == 0)return dxlist;
		if (strcmp(ty, "map"))return dxmap;
		if (strcmp(ty, "table"))return dxtable;
		
		return dxnull;
	};

	typedef char*  uchar;
	typedef string ustring;

	inline int hextoi(const char* s) {
		int i = strtoul(s, NULL, 0);
		return i;
	}

	inline bool istoken(char p, char* chs)
	{
		char* pc = chs;
		while (*pc != '\0' && p != *pc)pc++;
		return *pc != '\0';
	}

	inline void tokenize(char* source, vector<char*>& tokens, char* chs = ",| ")
	{
		char* p = source;
		char* pre = p;
		while (*p != '\0')
		{
			if (istoken(*p, chs)) { *p = '\0'; pre = p + 1; }
			if (pre != NULL && istoken(*pre, chs))
				pre++;
			else if (pre != NULL)
			{
				tokens.push_back(pre);
				pre = NULL;
			}
			p++;
		}
	}

	inline void tokenize(const char* source, vector<ustring>& tokens, char* chs = ",| ")
	{
		char* cp = new char[strlen(source) + 1];
		strcpy(cp, source);
		vector<char*> vs;
		tokenize(cp, vs, chs);
		for (vector<char*>::iterator it = vs.begin(); it != vs.end(); it++)
		{
			tokens.push_back(ustring(*it));
		}
		delete cp;
	}

	inline void parse_float_list(const char* src, float* p, int& n)
	{
		char tokenBuffer[1024];
		strcpy(tokenBuffer, src);
		vector<char*> vs;
		tokenize(tokenBuffer, vs, " ,");
		if (n == 0) n = vs.size();
		for (int i = 0; i<n&&i<vs.size(); i++)
		{
			p[i] = atof(vs[i]);
		}
	}
	inline void parse_integer_list(const char* src, int* p, int& n)
	{
		char tokenBuffer[1024];
		strcpy(tokenBuffer, src);
		vector<char*> vs;
		tokenize(tokenBuffer, vs, " ,");
		if (n == 0) n = vs.size();
		for (int i = 0; i<n&&n<vs.size(); i++)p[i] = atoi(vs[i]);
	}
	inline void parse_hex_list(const char* src, int* p, int n)
	{
		char tokenBuffer[1024];
		strcpy(tokenBuffer, src);
		vector<char*> vs;
		tokenize(tokenBuffer, vs, " ,");
		for (int i = 0; i<n&&n<vs.size(); i++)p[i] = hextoi(vs[i]);
	}

	inline bool parse_bool(const char* b)
	{
		ustring _b(b);
		if (_b == ustring("1"))return true;
		if (_b == ustring("0"))return false;
		if (_b == ustring("true"))return true;
		if (_b == ustring("false"))return false;
		return false;
	}

	inline void parse_key_value_list(const char* str, map<ustring, ustring>& keyValueList)
	{
		vector<ustring> tokens;
		tokenize(str, tokens, ";");
		for (int i = 0; i<tokens.size(); i++) {
			vector<ustring> pair;
			tokenize(tokens[i].c_str(), pair, "=");
			keyValueList[pair[0]] = pair[1];
		}
	}

	inline std::string utf16_to_utf8(std::wstring const& wstr)
	{
		std::string str;
		int size = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, 0, 0, 0, 0);
		if (size > 0)
		{
			std::vector<char> buffer(size);
			WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &buffer[0], size, 0, 0);
			str.assign(buffer.begin(), buffer.end() - 1);
		}
		return str;
	}

	inline std::wstring utf8_to_utf16(std::string const& str)
	{
		std::wstring wstr;
		int size = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, 0, 0);
		if (size > 0)
		{
			std::vector<wchar_t> buffer(size);
			MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, &buffer[0], size);
			wstr.assign(buffer.begin(), buffer.end() - 1);
		}
		return wstr;
	}
}